home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / misc / splines.lha / Splines / cmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-16  |  7.1 KB  |  321 lines

  1. /* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
  2.  * Permission is granted for use and free distribution as long as the
  3.  * original author's name is included with the code.
  4.  */
  5.  
  6. /*
  7.  * Reformatted, and modified to compile without warnings and errors
  8.  * under SAS/C -6.5x by gduncan@philips.oz.au (GMD). This included
  9.  * proto generation, renaming of some literals to avoid name collisions,
  10.  * and Amiga Version string (also displayed in Title bar).
  11.  * No original version number, this version arbitrarily named 1.1. 
  12.  * - otherwise no functional changes.
  13.  * GMD - Sep 94
  14.  */
  15.  
  16. #include "all.h"
  17.  
  18.  
  19. int DrawAFrame = TRUE;
  20. int CurveType = OPENB_NATURAL;
  21.  
  22.  
  23. /* InRange : returns TRUE iff the mouse position is in the selection
  24.  * range of the given control point position
  25.  */
  26.  
  27. int
  28. InRange (mouse, control)
  29.      REAL_POINT *mouse, *control;
  30. {
  31.   return ((mouse->x >= control->x - CONTROL_RADIUS) &&
  32.       (mouse->x <= control->x + CONTROL_RADIUS) &&
  33.       (mouse->y >= control->y - CONTROL_RADIUS) &&
  34.       (mouse->y <= control->y + CONTROL_RADIUS));
  35. }
  36.  
  37. /* Select_ControlPoint : returns the member of Control_Points that is
  38.  * is selected at <x,y>. Returns FALSE if no point is selected.
  39.  */
  40.  
  41. DLISTPTR
  42. Select_ControlPoint (x, y)
  43.      SHORT x, y;
  44. {
  45.   REAL_POINT tmp;
  46.   int InRange ();
  47.   DLISTPTR Find_Element ();
  48.  
  49.   tmp.x = (float) x;
  50.   tmp.y = (float) y;
  51.   return (Find_Element (&tmp, &Control_Points, InRange));
  52. }
  53.  
  54.  
  55. /* Print Instruction: prints a string in the upper left hand corner
  56.  * of the window.  Assumes that the current pen color is the the
  57.  * color you want the string to appear in.
  58.  */
  59.  
  60. void
  61. PrintInstruction (w, instr)
  62.      WINDOW *w;
  63.      char *instr;
  64. {
  65.   Move (w->RPort, w->LeftEdge + w->BorderLeft + 1,
  66.     w->TopEdge + w->BorderTop + 1);
  67.   Text (w->RPort, instr, strlen (instr));
  68. }
  69.  
  70. /* GetPoint : Waits for the user to select a point in window <w> and returns its
  71.  * x,y coordinates in terms of a REAL_POINT structure.
  72.  */
  73.  
  74.  
  75. DLISTPTR
  76. GetPoint (w)
  77.      WINDOW *w;
  78. {
  79.   REAL_POINT *tmp;
  80.   DLISTPTR p;
  81.   INTUIMESSAGE mcopy, *msg;
  82.   RASTPORT *rp = w->RPort;
  83.   BYTE old_mode = rp->DrawMode;
  84.  
  85.   if (!((tmp = (REAL_POINT *) calloc (1, sizeof (REAL_POINT))) &&
  86.     (p = (DLISTPTR) calloc (1, sizeof (DLIST_ELEMENT)))))
  87.     {
  88.       fprintf (stderr, "splines : trouble in paradise : can't allocate point\n");
  89.       panic (0);
  90.     }
  91.   SetDrMd (rp, COMPLEMENT);
  92.   PrintInstruction (w, "Select A Point");
  93.   while (1)
  94.     {
  95.       Wait (1 << w->UserPort->mp_SigBit);
  96.       while (msg = (INTUIMESSAGE *) GetMsg (w->UserPort))
  97.     {
  98.       mcopy = *msg;
  99.       ReplyMsg ((MESSAGE *) msg);
  100.       if ((msg->Class == MOUSEBUTTONS) && (msg->Code == SELECTDOWN) &&
  101.           Inside_Window (msg->MouseX, msg->MouseY, w))
  102.         {
  103.           tmp->x = (float) msg->MouseX;
  104.           tmp->y = (float) msg->MouseY;
  105.           PrintInstruction (w, "Select A Point");
  106.           SetDrMd (rp, old_mode);
  107.           PlopDot (w, tmp);
  108.           p->contents = tmp;
  109.           return (p);
  110.         }
  111.     }
  112.     }
  113. }
  114.  
  115.  
  116. /* PrintError: prints a error string to the window's upper left hand
  117.  * corner for approx. 1.6 seconds.  The string is drawn in the complement
  118.  * of the background so that it doesn't destroy what's already drawn in the
  119.  * window. After the delay, the string is complemented out again so it
  120.  * disappears.
  121.  */
  122.  
  123. void
  124. PrintError (w, str)
  125.      WINDOW *w;
  126.      char *str;
  127. {
  128.   RASTPORT *rp = w->RPort;
  129.   BYTE old_mode = rp->DrawMode;
  130.   SetDrMd (rp, COMPLEMENT);
  131.   PrintInstruction (w, str);
  132.   Delay (80l);
  133.   PrintInstruction (w, str);
  134.   SetDrMd (rp, old_mode);
  135. }
  136.  
  137. void
  138. DrawConstructionLine (w, p0, p1)    /* draws a dotted line from p0 to p1 */
  139.      WINDOW *w;
  140.      REAL_POINT *p0, *p1;
  141. {
  142.   RASTPORT *rp = w->RPort;
  143.   BYTE old_pen = rp->FgPen;    /* save the old pen color */
  144.   USHORT old_pat = rp->LinePtrn;    /* save the old line pattern */
  145.  
  146.   SetAPen (rp, AFRAME_COLOR);
  147.   SetDrPt (rp, 0xcccc);        /* use a dotted line */
  148.   Move (rp, (SHORT) p0->x, (SHORT) p0->y);
  149.   Draw (rp, (SHORT) p1->x, (SHORT) p1->y);
  150.   SetDrPt (rp, old_pat);
  151.   SetAPen (rp, old_pen);
  152.  
  153. }
  154.  
  155. /* Edit_Curve : pops up the curve style editing menu in <w> and allows
  156.  * the user to alter the current curve style
  157.  */
  158. void
  159. Edit_CurveStyle (w)
  160.      WINDOW *w;
  161. {
  162.   int option = PopUp (&CurveMenu, w);
  163.   switch (option)
  164.     {
  165.     case TOGGLEAFRAME:
  166.       DrawAFrame = !DrawAFrame;
  167.       Redraw (w);
  168.       break;
  169.     case REDRAW:
  170.       Redraw (w);
  171.       break;
  172.     case OPENB_TRIPLE:
  173.       if (LENGTH (&Control_Points) < 4)
  174.     {
  175.       PrintError (w, "?Error: Triple Knot option require minimum of 4 points");
  176.       return;
  177.     }
  178.       /* othewise fall through to action for the next case */
  179.     case OPENB_NATURAL:
  180.     case CLOSEDB:
  181.     case CLOSED_INTRPL:
  182.     case OPEN_INTRPL:
  183.       if (option != CurveType)
  184.     {
  185.       CurveType = option;
  186.       Redraw (w);
  187.     }
  188.       break;
  189.     case QUIT:
  190.       close_things ();
  191.       exit (0);
  192.       break;
  193.     }
  194. }
  195.  
  196.  
  197. /* Edit_ControlPoint : pops up the control point editing menu in <w> and
  198.  * allows the user to alter the given control point <p>.  Assumes
  199.  * that <p> is the control point that the user just selected.
  200.  */
  201.  
  202. void
  203. Edit_ControlPoint (w, p)
  204.      WINDOW *w;
  205.      DLISTPTR p;
  206. {
  207.   int option = PopUp (&PointMenu, w);
  208.   switch (option)
  209.     {
  210.     case ADD_AFTER:
  211.       if (LENGTH (&Control_Points) == MAXG)
  212.     {
  213.       PrintError (w, "No! Don't you think you've added enough points?");
  214.       return;
  215.     }
  216.       else
  217.     Insert_After (p, GetPoint (w), &Control_Points);
  218.       break;
  219.  
  220.     case ADD_BEFORE:
  221.       if (LENGTH (&Control_Points) == MAXG)
  222.     {
  223.       PrintError (w, "No! Don't you think you've added enough points?");
  224.       return;
  225.     }
  226.       else
  227.     Insert_Before (p, GetPoint (w), &Control_Points);
  228.       break;
  229.  
  230.     case MOVE_POINT:
  231.       {
  232.     DLISTPTR tmp;
  233.     EraseDot (w, p->contents);
  234.     free (p->contents);
  235.     tmp = GetPoint (w);
  236.     p->contents = tmp->contents;
  237.     free (tmp);
  238.     break;
  239.       }
  240.     case REMOVE_POINT:
  241.       {
  242.     int len = LENGTH (&Control_Points);
  243.     if ((len == 4) && (CurveType == OPENB_TRIPLE))
  244.       {
  245.         PrintError (w, "?Error: Triple Knot option require minimum of 4 points");
  246.         return;
  247.       }
  248.     else if (len == 3)
  249.       PrintError (w, "?Error: you must have a minimum of 3 control points");
  250.     else
  251.       {
  252.         Remove_Element (p, &Control_Points);
  253.         free (p->contents);
  254.         free (p);
  255.       }
  256.       }
  257.       break;
  258.     default:
  259.       return;
  260.     }
  261.   Redraw (w);
  262. }
  263.  
  264. void
  265. EraseDot (w, dot)
  266.      WINDOW *w;
  267.      REAL_POINT *dot;
  268. {
  269.   control_image.PlanePick = 0;
  270.   PlopDot (w, dot);
  271.   control_image.PlanePick = 1;
  272. }
  273.  
  274. void
  275. PlopDot (w, point)
  276.      WINDOW *w;
  277.      REAL_POINT *point;
  278. {
  279.   DrawImage (w->RPort, &control_image, (SHORT) point->x, (SHORT) point->y);
  280. }
  281.  
  282. void
  283. Draw_ControlPoints (w)
  284.      WINDOW *w;
  285. {
  286.   DLISTPTR tmp = &Control_Points;
  287.   while ((tmp = tmp->next) != &Control_Points)
  288.     PlopDot (w, POINT (tmp));
  289. }
  290.  
  291. void
  292. Redraw (w)
  293.      WINDOW *w;
  294. {
  295.   RASTPORT *rp = w->RPort;
  296.   SetRast (rp, ERASE);
  297.   SetAPen (rp, CURVECOLOR);
  298.   Draw_ControlPoints (w);
  299.   switch (CurveType)
  300.     {
  301.     case CLOSEDB:
  302.       Draw_Closed_Bspline (w, &Control_Points);
  303.       break;
  304.     case CLOSED_INTRPL:
  305.       Draw_Closed_Ispline (w, &Control_Points);
  306.       break;
  307.     case OPEN_INTRPL:
  308.       Draw_Open_Ispline (w, &Control_Points);
  309.       break;
  310.     case OPENB_TRIPLE:
  311.       Draw_TripleKnot_Bspline (w, &Control_Points);
  312.       break;
  313.     default:
  314.       Draw_Natural_Bspline (w, &Control_Points);
  315.       break;
  316.     }
  317. }
  318.  
  319. /*--*/
  320. €
  321.